package git.bankview.sl.report;

import java.util.*;
import java.sql.*;
import java.io.*;

import laya.semi.process.*;

import git.bankview.sl.db.*;

import org.apache.log4j.Logger;

public class ReportScheduler
{
	private static Logger log = Logger.getLogger(ReportScheduler.class);
	
	private Vector m_oThreads = new Vector();
	private Vector m_oSchdQueue = new Vector();
	private int m_nThreadPollInterval = -1;
	
	public ReportScheduler(int nThreads, int threadPollInterval)
		throws Exception
	{
		m_nThreadPollInterval = threadPollInterval;
		
		for (int i = 0; i < nThreads; ++i)
		{
			ReportProcessThread thread = new ReportProcessThread(this, i, m_nThreadPollInterval);
			m_oThreads.addElement(thread);
			thread.start();
		}
	}
	
	public void setReportProcessThreads(int nThreads)
	{
		synchronized(m_oThreads)
		{
			if (nThreads < m_oThreads.size())
			{
				for (int i = m_oThreads.size() - 1; i >= nThreads; --i)
				{
					ReportProcessThread thread = (ReportProcessThread)m_oThreads.get(i);
					thread.setTerminateFlag();
					m_oThreads.remove(i);
				}
			}
			else if (nThreads > m_oThreads.size())
			{
				while(nThreads > m_oThreads.size())
				{
					ReportProcessThread thread = new ReportProcessThread(this, m_oThreads.size(), m_nThreadPollInterval);
					m_oThreads.addElement(thread);
					thread.start();
				}
			}
		}
	}
	
	// return schedule's count after add
	public int addSchedule(int nSchdId)
	{
		log.debug("addSchedule(" + nSchdId + ")");
		Integer schd = new Integer(nSchdId);
		
		synchronized(m_oSchdQueue)
		{
			if (!m_oSchdQueue.contains(schd))
				m_oSchdQueue.addElement(schd);
		}
		
		synchronized(m_oThreads)
		{
			for (int i = 0; i < m_oThreads.size(); ++i)
			{
				ReportProcessThread thread = (ReportProcessThread)m_oThreads.get(i);
				if (thread.isWaitForNewSchd())
				{
					//log.debug(i + ".interrupt() for " + nSchdId);
					thread.interrupt();
					break;
				}
			}
		}
		
		return m_oSchdQueue.size();
	}
	
	public int releaseSchedule()
	{
		synchronized(m_oSchdQueue)
		{
			if (0 < m_oSchdQueue.size())
				return ((Integer)m_oSchdQueue.remove(0)).intValue();
		}
		
		return -1;
	}
	
	public void destroy()
	{
		synchronized(m_oThreads)
		{
			for (int i = 0; i < m_oThreads.size(); ++i)
			{
				ReportProcessThread thread = (ReportProcessThread)m_oThreads.get(i);
				thread.setTerminateFlag();
			}
		}
	}
}
